package reflect01;

import org.junit.Test;

import java.lang.reflect.Field;

/**
 * 反射(解刨出)字段/成员变量
 *  Class类中的方法:
 *      public Field getField(String name)
 *      name:字段的名称(即成员变量的名称)
 *      获取的是共有的成员变量
 *  Field类中的方法:
 *      public Field getDeclaredField(String name): 根据字段名称获取任意字段
 *      public Object get(Object obj):获取1某个对象中的属性值
 *      public void set(Object obj, Object value):将指定对象(obj)中的属性值设置成指定值(value)
 *      public void setAccessible(boolean flag):设置是否跳过对于java的权限访问检查,传入true则跳过，false则不跳过
 */
public class ReflectDemo04 {
    @Test
    public void testMethod01()throws Exception{
        //1.获取字节码对象
        Class<Person> pCls = Person.class;

        //2.获取指定的字段
        Field f =pCls.getField("name");

        //3.获取该字段的值
        Person person = pCls.getConstructor().newInstance();//类比: Person person = new Person();
        Object val = f.get(person);//类比: person.name
        System.out.println(val);

        //4.设置该字段的值
        f.set(person,"老王");//类比: person.name="老王"
        System.out.println(f.get(person));
    }

    @Test
    public void teatMethod02()throws Exception{
        //1.获取字节码对象
        Class<Person> pCls = Person.class;

        //2.获取指定的字段
        Field f = pCls.getDeclaredField("age");

        //3.绕过java权限检查
        f.setAccessible(true);

        //4.获取当前字段的值
        Person person = pCls.getConstructor().newInstance();//类比: Person p = new Person();
        System.out.println(f.get(person));;//类比: p.age通过java代码调取不到 (底层是暴力反射)
    }
}
